From d61a71590942ece5da40a21bd80d77751147e99e Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 27 Sep 2017 20:56:01 -0400 Subject: [PATCH] vulkan: Implement multiple render passes Whenever we need a node as a texture, we now start a new render pass that renders the node into a new intermediate texture, and set up a semaphore to make the current render pass wait for it. As part of this reorganization, much of the setup and drawing code moved from gskvulkanrender.c to gskvulkanrenderpass.c. --- gsk/gskvulkanrender.c | 204 ++++++++++--------------- gsk/gskvulkanrenderer.c | 1 + gsk/gskvulkanrenderpass.c | 255 +++++++++++++++++++++++++++---- gsk/gskvulkanrenderpassprivate.h | 25 ++- gsk/gskvulkanrenderprivate.h | 9 ++ 5 files changed, 324 insertions(+), 170 deletions(-) diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c index 58888667b5..06b593c422 100644 --- a/gsk/gskvulkanrender.c +++ b/gsk/gskvulkanrender.c @@ -23,9 +23,6 @@ #include "gskvulkantextpipelineprivate.h" #include "gskvulkanpushconstantsprivate.h" -#define ORTHO_NEAR_PLANE -10000 -#define ORTHO_FAR_PLANE 10000 - #define DESCRIPTOR_POOL_MAXSETS 128 #define DESCRIPTOR_POOL_MAXSETS_INCREASE 128 @@ -34,7 +31,6 @@ struct _GskVulkanRender GskRenderer *renderer; GdkVulkanContext *vulkan; - graphene_matrix_t mvp; int scale_factor; VkRect2D viewport; cairo_region_t *clip; @@ -46,7 +42,6 @@ struct _GskVulkanRender VkDescriptorSetLayout descriptor_set_layout; VkPipelineLayout pipeline_layout[3]; /* indexed by number of textures */ GskVulkanUploader *uploader; - GskVulkanBuffer *vertex_buffer; GHashTable *descriptor_set_indexes; VkDescriptorPool descriptor_pool; @@ -57,7 +52,7 @@ struct _GskVulkanRender GskVulkanImage *target; - GSList *render_passes; + GList *render_passes; GSList *cleanup_images; }; @@ -67,7 +62,6 @@ gsk_vulkan_render_setup (GskVulkanRender *self, const graphene_rect_t *rect) { GdkWindow *window = gsk_renderer_get_window (self->renderer); - graphene_matrix_t modelview, projection; self->target = g_object_ref (target); @@ -88,15 +82,6 @@ gsk_vulkan_render_setup (GskVulkanRender *self, self->viewport.extent.height = gdk_window_get_height (window) * self->scale_factor; self->clip = gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (self->renderer)); } - - graphene_matrix_init_scale (&modelview, self->scale_factor, self->scale_factor, 1.0); - graphene_matrix_init_ortho (&projection, - self->viewport.offset.x, self->viewport.offset.x + self->viewport.extent.width, - self->viewport.offset.y, self->viewport.offset.y + self->viewport.extent.height, - ORTHO_NEAR_PLANE, - ORTHO_FAR_PLANE); - - graphene_matrix_multiply (&modelview, &projection, &self->mvp); } GskVulkanRender * @@ -243,7 +228,7 @@ gsk_vulkan_render_remove_framebuffer_from_image (gpointer data, g_slice_free (HashFramebufferEntry, fb); } -static VkFramebuffer +VkFramebuffer gsk_vulkan_render_get_framebuffer (GskVulkanRender *self, GskVulkanImage *image) { @@ -285,70 +270,69 @@ void gsk_vulkan_render_add_node (GskVulkanRender *self, GskRenderNode *node) { - GskVulkanRenderPass *pass = gsk_vulkan_render_pass_new (self->vulkan); - - self->render_passes = g_slist_prepend (self->render_passes, pass); - - gsk_vulkan_render_pass_add (pass, - self, - &self->mvp, - &GRAPHENE_RECT_INIT ( - self->viewport.offset.x, self->viewport.offset.y, - self->viewport.extent.width, self->viewport.extent.height - ), - node); + GskVulkanRenderPass *pass; + + pass = gsk_vulkan_render_pass_new (self->vulkan, + self->target, + self->scale_factor, + &GRAPHENE_RECT_INIT ( + self->viewport.offset.x, self->viewport.offset.y, + self->viewport.extent.width, self->viewport.extent.height + ), + self->clip, + VK_NULL_HANDLE); + + self->render_passes = g_list_prepend (self->render_passes, pass); + + gsk_vulkan_render_pass_add (pass, self, node); } void -gsk_vulkan_render_upload (GskVulkanRender *self) +gsk_vulkan_render_add_node_for_texture (GskVulkanRender *self, + GskRenderNode *node, + const graphene_rect_t *bounds, + GskVulkanImage *target, + VkSemaphore semaphore) { - GSList *l; + GskVulkanRenderPass *pass; + cairo_region_t *clip; - for (l = self->render_passes; l; l = l->next) - { - gsk_vulkan_render_pass_upload (l->data, self, self->uploader); - } + clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { + 0, 0, + gsk_vulkan_image_get_width (target), + gsk_vulkan_image_get_height (target) + }); - gsk_vulkan_uploader_upload (self->uploader); -} + pass = gsk_vulkan_render_pass_new (self->vulkan, + target, + 1, + bounds, + clip, + semaphore); -static gsize -gsk_vulkan_renderer_count_vertex_data (GskVulkanRender *self) -{ - gsize n_bytes; - GSList *l; + cairo_region_destroy (clip); - n_bytes = 0; - for (l = self->render_passes; l; l = l->next) - { - n_bytes += gsk_vulkan_render_pass_count_vertex_data (l->data); - } + self->render_passes = g_list_prepend (self->render_passes, pass); - return n_bytes; + gsk_vulkan_render_pass_add (pass, self, node); } -static GskVulkanBuffer * -gsk_vulkan_render_collect_vertex_data (GskVulkanRender *self) +void +gsk_vulkan_render_upload (GskVulkanRender *self) { - GskVulkanBuffer *buffer; - guchar *data; - GSList *l; - gsize offset, n_bytes; - - offset = 0; - n_bytes = gsk_vulkan_renderer_count_vertex_data (self); - buffer = gsk_vulkan_buffer_new (self->vulkan, n_bytes); - data = gsk_vulkan_buffer_map (buffer); + GList *l; - for (l = self->render_passes; l; l = l->next) + /* gsk_vulkan_render_pass_upload may call gsk_vulkan_render_add_node_for_texture, + * prepending new render passes to the list. Therefore, we walk the list from + * the end. + */ + for (l = g_list_last (self->render_passes); l; l = l->prev) { - offset += gsk_vulkan_render_pass_collect_vertex_data (l->data, self, data, offset, n_bytes - offset); - g_assert (offset <= n_bytes); + GskVulkanRenderPass *pass = l->data; + gsk_vulkan_render_pass_upload (pass, self, self->uploader); } - gsk_vulkan_buffer_unmap (buffer); - - return buffer; + gsk_vulkan_uploader_upload (self->uploader); } GskVulkanPipeline * @@ -424,6 +408,8 @@ gsk_vulkan_render_reserve_descriptor_set (GskVulkanRender *self, { gpointer id_plus_one; + g_assert (source != NULL); + id_plus_one = g_hash_table_lookup (self->descriptor_set_indexes, source); if (id_plus_one) return GPOINTER_TO_SIZE (id_plus_one) - 1; @@ -441,14 +427,15 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self, GHashTableIter iter; gpointer key, value; VkDevice device; - GSList *l; + GList *l; guint i, needed_sets; device = gdk_vulkan_context_get_device (self->vulkan); for (l = self->render_passes; l; l = l->next) { - gsk_vulkan_render_pass_reserve_descriptor_sets (l->data, self); + GskVulkanRenderPass *pass = l->data; + gsk_vulkan_render_pass_reserve_descriptor_sets (pass, self); } needed_sets = g_hash_table_size (self->descriptor_set_indexes); @@ -534,68 +521,35 @@ void gsk_vulkan_render_draw (GskVulkanRender *self, VkSampler sampler) { - VkCommandBuffer command_buffer; - GSList *l; - guint i; + GList *l; gsk_vulkan_render_prepare_descriptor_sets (self, sampler); - command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool); - - self->vertex_buffer = gsk_vulkan_render_collect_vertex_data (self); - - vkCmdSetViewport (command_buffer, - 0, - 1, - &(VkViewport) { - .x = 0, - .y = 0, - .width = self->viewport.extent.width, - .height = self->viewport.extent.height, - .minDepth = 0, - .maxDepth = 1 - }); - - for (i = 0; i < cairo_region_num_rectangles (self->clip); i++) + for (l = self->render_passes; l; l = l->next) { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (self->clip, i, &rect); - - vkCmdSetScissor (command_buffer, - 0, - 1, - &(VkRect2D) { - { rect.x * self->scale_factor, rect.y * self->scale_factor }, - { rect.width * self->scale_factor, rect.height * self->scale_factor } - }); - - vkCmdBeginRenderPass (command_buffer, - &(VkRenderPassBeginInfo) { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .renderPass = self->render_pass, - .framebuffer = gsk_vulkan_render_get_framebuffer (self, self->target), - .renderArea = { - { rect.x * self->scale_factor, rect.y * self->scale_factor }, - { rect.width * self->scale_factor, rect.height * self->scale_factor } - }, - .clearValueCount = 1, - .pClearValues = (VkClearValue [1]) { - { .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } } - } - }, - VK_SUBPASS_CONTENTS_INLINE); - - for (l = self->render_passes; l; l = l->next) - { - gsk_vulkan_render_pass_draw (l->data, self, self->vertex_buffer, 3, self->pipeline_layout, command_buffer); - } - - vkCmdEndRenderPass (command_buffer); + GskVulkanRenderPass *pass = l->data; + VkCommandBuffer command_buffer; + gsize wait_semaphore_count; + gsize signal_semaphore_count; + VkSemaphore *wait_semaphores; + VkSemaphore *signal_semaphores; + + wait_semaphore_count = gsk_vulkan_render_pass_get_wait_semaphores (pass, &wait_semaphores); + signal_semaphore_count = gsk_vulkan_render_pass_get_signal_semaphores (pass, &signal_semaphores); + + command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool); + + gsk_vulkan_render_pass_draw (pass, self, 3, self->pipeline_layout, command_buffer); + + gsk_vulkan_command_pool_submit_buffer (self->command_pool, + command_buffer, + wait_semaphore_count, + wait_semaphores, + signal_semaphore_count, + signal_semaphores, + l->next != NULL ? VK_NULL_HANDLE : self->fence); } - gsk_vulkan_command_pool_submit_buffer (self->command_pool, command_buffer, 0, NULL, 0, NULL, self->fence); - if (GSK_RENDER_MODE_CHECK (SYNC)) { GSK_VK_CHECK (vkWaitForFences, gdk_vulkan_context_get_device (self->vulkan), @@ -634,14 +588,12 @@ gsk_vulkan_render_cleanup (GskVulkanRender *self) gsk_vulkan_command_pool_reset (self->command_pool); - g_clear_pointer (&self->vertex_buffer, gsk_vulkan_buffer_free); - g_hash_table_remove_all (self->descriptor_set_indexes); GSK_VK_CHECK (vkResetDescriptorPool, device, self->descriptor_pool, 0); - g_slist_free_full (self->render_passes, (GDestroyNotify) gsk_vulkan_render_pass_free); + g_list_free_full (self->render_passes, (GDestroyNotify) gsk_vulkan_render_pass_free); self->render_passes = NULL; g_slist_free_full (self->cleanup_images, g_object_unref); self->cleanup_images = NULL; diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c index 6666880e7f..661128cc09 100644 --- a/gsk/gskvulkanrenderer.c +++ b/gsk/gskvulkanrenderer.c @@ -246,6 +246,7 @@ gsk_vulkan_renderer_render (GskRenderer *renderer, #ifdef G_ENABLE_DEBUG profiler = gsk_renderer_get_profiler (renderer); + gsk_profiler_counter_set (profiler, self->profile_counters.fallback_pixels, 0); gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time); #endif diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c index 022c08d74e..e82c4a2da1 100644 --- a/gsk/gskvulkanrenderpass.c +++ b/gsk/gskvulkanrenderpass.c @@ -27,6 +27,9 @@ #include +#define ORTHO_NEAR_PLANE -10000 +#define ORTHO_FAR_PLANE 10000 + typedef union _GskVulkanOp GskVulkanOp; typedef struct _GskVulkanOpRender GskVulkanOpRender; typedef struct _GskVulkanOpText GskVulkanOpText; @@ -107,17 +110,97 @@ struct _GskVulkanRenderPass GArray *render_ops; + GskVulkanImage *target; + int scale_factor; + graphene_rect_t viewport; + cairo_region_t *clip; + graphene_matrix_t mvp; + + VkRenderPass render_pass; + VkSemaphore signal_semaphore; + GArray *wait_semaphores; + GskVulkanBuffer *vertex_data; + GQuark fallback_pixels; }; GskVulkanRenderPass * -gsk_vulkan_render_pass_new (GdkVulkanContext *context) +gsk_vulkan_render_pass_new (GdkVulkanContext *context, + GskVulkanImage *target, + int scale_factor, + graphene_rect_t *viewport, + cairo_region_t *clip, + VkSemaphore signal_semaphore) { GskVulkanRenderPass *self; + graphene_matrix_t modelview, projection; + VkImageLayout final_layout; self = g_slice_new0 (GskVulkanRenderPass); self->vulkan = g_object_ref (context); self->render_ops = g_array_new (FALSE, FALSE, sizeof (GskVulkanOp)); + + self->target = g_object_ref (target); + self->scale_factor = scale_factor; + self->clip = cairo_region_copy (clip); + self->viewport = GRAPHENE_RECT_INIT (0, 0, viewport->size.width, viewport->size.height); + + graphene_matrix_init_scale (&modelview, self->scale_factor, self->scale_factor, 1.0); + graphene_matrix_init_ortho (&projection, + viewport->origin.x, viewport->origin.x + viewport->size.width, + viewport->origin.y, viewport->origin.y + viewport->size.height, + ORTHO_NEAR_PLANE, + ORTHO_FAR_PLANE); + graphene_matrix_multiply (&modelview, &projection, &self->mvp); + + if (signal_semaphore != VK_NULL_HANDLE) // this is a dependent pass + final_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + else + final_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + GSK_VK_CHECK (vkCreateRenderPass, gdk_vulkan_context_get_device (self->vulkan), + &(VkRenderPassCreateInfo) { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .attachmentCount = 1, + .pAttachments = (VkAttachmentDescription[]) { + { + .format = gdk_vulkan_context_get_image_format (self->vulkan), + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR, + .storeOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .finalLayout = final_layout + } + }, + .subpassCount = 1, + .pSubpasses = (VkSubpassDescription []) { + { + .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .inputAttachmentCount = 0, + .colorAttachmentCount = 1, + .pColorAttachments = (VkAttachmentReference []) { + { + .attachment = 0, + .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL + } + }, + .pResolveAttachments = (VkAttachmentReference []) { + { + .attachment = VK_ATTACHMENT_UNUSED, + .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL + } + }, + .pDepthStencilAttachment = NULL, + } + }, + .dependencyCount = 0 + }, + NULL, + &self->render_pass); + + self->signal_semaphore = signal_semaphore; + self->wait_semaphores = g_array_new (FALSE, FALSE, sizeof (VkSemaphore)); + self->vertex_data = NULL; + #ifdef G_ENABLE_DEBUG self->fallback_pixels = g_quark_from_static_string ("fallback-pixels"); #endif @@ -130,6 +213,19 @@ gsk_vulkan_render_pass_free (GskVulkanRenderPass *self) { g_array_unref (self->render_ops); g_object_unref (self->vulkan); + g_object_unref (self->target); + cairo_region_destroy (self->clip); + vkDestroyRenderPass (gdk_vulkan_context_get_device (self->vulkan), + self->render_pass, + NULL); + if (self->vertex_data) + gsk_vulkan_buffer_free (self->vertex_data); + if (self->signal_semaphore != VK_NULL_HANDLE) + vkDestroySemaphore (gdk_vulkan_context_get_device (self->vulkan), + self->signal_semaphore, + NULL); + g_array_unref (self->wait_semaphores); + g_slice_free (GskVulkanRenderPass, self); } @@ -530,14 +626,12 @@ fallback: void gsk_vulkan_render_pass_add (GskVulkanRenderPass *self, GskVulkanRender *render, - const graphene_matrix_t *mvp, - const graphene_rect_t *viewport, GskRenderNode *node) { GskVulkanOp op = { 0, }; op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS; - gsk_vulkan_push_constants_init (&op.constants.constants, mvp, viewport); + gsk_vulkan_push_constants_init (&op.constants.constants, &self->mvp, &self->viewport); g_array_append_val (self->render_ops, op); gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, node); @@ -559,15 +653,39 @@ gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass *self, switch (gsk_render_node_get_node_type (node)) { case GSK_TEXTURE_NODE: - return gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)), - gsk_texture_node_get_texture (node), - uploader); + result = gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)), + gsk_texture_node_get_texture (node), + uploader); + gsk_vulkan_render_add_cleanup_image (render, result); + return result; + case GSK_CAIRO_NODE: surface = cairo_surface_reference (gsk_cairo_node_get_surface (node)); goto got_surface; - default: - break; + default: ; + { + VkSemaphore semaphore; + + result = gsk_vulkan_image_new_for_texture (self->vulkan, + ceil (bounds->size.width), + ceil (bounds->size.height)); + + vkCreateSemaphore (gdk_vulkan_context_get_device (self->vulkan), + &(VkSemaphoreCreateInfo) { + VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + NULL, + 0 + }, + NULL, + &semaphore); + + g_array_append_val (self->wait_semaphores, semaphore); + gsk_vulkan_render_add_node_for_texture (render, node, bounds, result, semaphore); + gsk_vulkan_render_add_cleanup_image (render, result); + + return result; + } } } @@ -756,7 +874,7 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, { GskRenderNode *child = gsk_color_matrix_node_get_child (op->render.node); - op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self, + op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self, render, uploader, child, @@ -813,7 +931,7 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, } } -gsize +static gsize gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self) { GskVulkanOp *op; @@ -892,6 +1010,7 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self) default: g_assert_not_reached (); + case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS: continue; } @@ -900,7 +1019,7 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self) return n_bytes; } -gsize +static gsize gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, GskVulkanRender *render, guchar *data, @@ -1124,23 +1243,39 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, return n_bytes; } -GskVulkanBuffer * +static GskVulkanBuffer * gsk_vulkan_render_pass_get_vertex_data (GskVulkanRenderPass *self, GskVulkanRender *render) { - gsize n_bytes; - GskVulkanBuffer *buffer; - guchar *data; - - n_bytes = gsk_vulkan_render_pass_count_vertex_data (self); - buffer = gsk_vulkan_buffer_new (self->vulkan, n_bytes); - data = gsk_vulkan_buffer_map (buffer); + if (self->vertex_data == NULL) + { + gsize n_bytes; + guchar *data; + + n_bytes = gsk_vulkan_render_pass_count_vertex_data (self); + self->vertex_data = gsk_vulkan_buffer_new (self->vulkan, n_bytes); + data = gsk_vulkan_buffer_map (self->vertex_data); + gsk_vulkan_render_pass_collect_vertex_data (self, render, data, 0, n_bytes); + gsk_vulkan_buffer_unmap (self->vertex_data); + } - gsk_vulkan_render_pass_collect_vertex_data (self, render, data, 0, n_bytes); + return self->vertex_data; +} - gsk_vulkan_buffer_unmap (buffer); +gsize +gsk_vulkan_render_pass_get_wait_semaphores (GskVulkanRenderPass *self, + VkSemaphore **semaphores) +{ + *semaphores = (VkSemaphore *)self->wait_semaphores->data; + return self->wait_semaphores->len; +} - return buffer; +gsize +gsk_vulkan_render_pass_get_signal_semaphores (GskVulkanRenderPass *self, + VkSemaphore **semaphores) +{ + *semaphores = (VkSemaphore *)&self->signal_semaphore; + return self->signal_semaphore != VK_NULL_HANDLE ? 1 : 0; } void @@ -1180,6 +1315,7 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self, default: g_assert_not_reached (); + case GSK_VULKAN_OP_COLOR: case GSK_VULKAN_OP_LINEAR_GRADIENT: case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS: @@ -1191,18 +1327,20 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self, } } -void -gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, - GskVulkanRender *render, - GskVulkanBuffer *vertex_buffer, - guint layout_count, - VkPipelineLayout *pipeline_layout, - VkCommandBuffer command_buffer) +static void +gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self, + GskVulkanRender *render, + guint layout_count, + VkPipelineLayout *pipeline_layout, + VkCommandBuffer command_buffer) { GskVulkanPipeline *current_pipeline = NULL; gsize current_draw_index = 0; GskVulkanOp *op; guint i, step; + GskVulkanBuffer *vertex_buffer; + + vertex_buffer = gsk_vulkan_render_pass_get_vertex_data (self, render); for (i = 0; i < self->render_ops->len; i += step) { @@ -1555,3 +1693,60 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, } } } + +void +gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, + GskVulkanRender *render, + guint layout_count, + VkPipelineLayout *pipeline_layout, + VkCommandBuffer command_buffer) +{ + guint i; + + vkCmdSetViewport (command_buffer, + 0, + 1, + &(VkViewport) { + .x = 0, + .y = 0, + .width = self->viewport.size.width, + .height = self->viewport.size.height, + .minDepth = 0, + .maxDepth = 1 + }); + + for (i = 0; i < cairo_region_num_rectangles (self->clip); i++) + { + cairo_rectangle_int_t rect; + + cairo_region_get_rectangle (self->clip, i, &rect); + + vkCmdSetScissor (command_buffer, + 0, + 1, + &(VkRect2D) { + { rect.x * self->scale_factor, rect.y * self->scale_factor }, + { rect.width * self->scale_factor, rect.height * self->scale_factor } + }); + + vkCmdBeginRenderPass (command_buffer, + &(VkRenderPassBeginInfo) { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .renderPass = self->render_pass, + .framebuffer = gsk_vulkan_render_get_framebuffer (render, self->target), + .renderArea = { + { rect.x * self->scale_factor, rect.y * self->scale_factor }, + { rect.width * self->scale_factor, rect.height * self->scale_factor } + }, + .clearValueCount = 1, + .pClearValues = (VkClearValue [1]) { + { .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } } + } + }, + VK_SUBPASS_CONTENTS_INLINE); + + gsk_vulkan_render_pass_draw_rect (self, render, layout_count, pipeline_layout, command_buffer); + + vkCmdEndRenderPass (command_buffer); + } +} diff --git a/gsk/gskvulkanrenderpassprivate.h b/gsk/gskvulkanrenderpassprivate.h index 808ea880e1..3af9470403 100644 --- a/gsk/gskvulkanrenderpassprivate.h +++ b/gsk/gskvulkanrenderpassprivate.h @@ -11,36 +11,33 @@ G_BEGIN_DECLS -GskVulkanRenderPass * gsk_vulkan_render_pass_new (GdkVulkanContext *context); +GskVulkanRenderPass * gsk_vulkan_render_pass_new (GdkVulkanContext *context, + GskVulkanImage *target, + int scale_factor, + graphene_rect_t *viewport, + cairo_region_t *clip, + VkSemaphore signal_semaphore); + void gsk_vulkan_render_pass_free (GskVulkanRenderPass *self); void gsk_vulkan_render_pass_add (GskVulkanRenderPass *self, GskVulkanRender *render, - const graphene_matrix_t*mvp, - const graphene_rect_t *viewport, GskRenderNode *node); void gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self, GskVulkanRender *render, GskVulkanUploader *uploader); - -gsize gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self); -gsize gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, - GskVulkanRender *render, - guchar *data, - gsize offset, - gsize total); -GskVulkanBuffer * gsk_vulkan_render_pass_get_vertex_data (GskVulkanRenderPass *self, - GskVulkanRender *render); - void gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self, GskVulkanRender *render); void gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, GskVulkanRender *render, - GskVulkanBuffer *vertex_buffer, guint layout_count, VkPipelineLayout *pipeline_layout, VkCommandBuffer command_buffer); +gsize gsk_vulkan_render_pass_get_wait_semaphores (GskVulkanRenderPass *self, + VkSemaphore **semaphores); +gsize gsk_vulkan_render_pass_get_signal_semaphores (GskVulkanRenderPass *self, + VkSemaphore **semaphores); G_END_DECLS diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h index 4bd2484d81..ec553be148 100644 --- a/gsk/gskvulkanrenderprivate.h +++ b/gsk/gskvulkanrenderprivate.h @@ -69,6 +69,13 @@ void gsk_vulkan_render_add_cleanup_image (GskVulk void gsk_vulkan_render_add_node (GskVulkanRender *self, GskRenderNode *node); +void gsk_vulkan_render_add_node_for_texture (GskVulkanRender *self, + GskRenderNode *node, + const graphene_rect_t *bounds, + GskVulkanImage *target, + VkSemaphore semaphore); + + void gsk_vulkan_render_upload (GskVulkanRender *self); GskVulkanPipeline * gsk_vulkan_render_get_pipeline (GskVulkanRender *self, @@ -83,6 +90,8 @@ void gsk_vulkan_render_draw (GskVulk void gsk_vulkan_render_submit (GskVulkanRender *self); GskTexture * gsk_vulkan_render_download_target (GskVulkanRender *self); +VkFramebuffer gsk_vulkan_render_get_framebuffer (GskVulkanRender *self, + GskVulkanImage *image); G_END_DECLS -- 2.30.2